<template>
  <el-input
      v-model="value_"
      :placeholder="placeholder"
      onKeyPress="return (/[\d\.\-]/.test(String.fromCharCode(event.keyCode)))"
      @focus="onfocus_"
      @blur="onblur_"
      @input="oninput_"
      clearable
      :name="name"
      :disabled="disabled"
      :prefix-icon="prefixIcon"
      :suffix-icon="suffixIcon"
      :readonly="readonly"
      :min="min"
      :max="max"
      :tabindex="tabIndex"
      :title="showTitle ? value_ : ''"
  >
    <template v-if="this.prepend!=null" #prepend>{{ this.prepend }}</template>
    <template v-if="this.append!=null" #append>{{ this.append }}</template>
  </el-input>
</template>

<script>
import {
  isNotVoid,isVoid
} from '@/utils/util'
export default {
  name: 'XFieldInputAmount',
  props: {
    /**input name */
    name: String,
    /**是否禁用 */
    disabled: {
      type: Boolean,
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    },
    /**属性value */
    value: Number,
    placeholder: {
      type: String,
      default: '请填写'
    },
    append: {
      type: String,
      default: null
    },
    prepend: {
      type: String,
      default: null
    },
    /**输入框头部图标 */
    prefixIcon: String,
    /**输入框尾部图标 */
    suffixIcon: String,
    /**小数位*/
    precision: {
      type: [String,Number],
      default: '2'
    },
    /**最小值 */
    min: {
      type: String,
      default: ''
    },
    /**最大值 */
    max: {
      type: Number,
      default: 1e20
    },
    /**
     *  输入框的tabindex
     */
    tabIndex: {
      type: String
    },
    showTitle:{
        type:Boolean,
        default:false
    }
  },
  data() {
    return {
      value_: 0,
      rawvalue_: 0
    }
  },
  created() {
    let precision = this.precision
    this.digType_ = new RegExp(
        '^-?([1-9]*\\.?|[1-9]\\d*|[1-9]\\d*\\.\\d{0,' + precision + '}|0\\.\\d{0,' + precision + '}|0)$'
    )
    if (this.value && !this.checkValid(this.value)) {
      return Number(this.value).toFixed(precision)
    }
    if (this.value) {
      this.value_ = this.value
      this.rawvalue_ = this.value
    }
  },
  watch: {
    value: {
      handler(v) {
        //判定 Infinity 无穷数
        if (!Number.isFinite(Number(v))){
          v = 0
        }
        let precision = this.precision
        if (v === this.rawvalue_&&isNotVoid(v)) return
        this.value_ = this.formatMoney(v)
        this.rawvalue_ = v
        if (!this.checkValid(v)) {
          this.rawvalue_ = Number(v).toFixed(precision)
        }
        this.$emit('input', this.rawvalue_)
        this.$emit('update:value', this.rawvalue_)
      }
    }
  },
  methods: {
    formatMoney(value) {
      if (typeof this.priceFormat === 'function') {
        return this.priceFormat(Number(value), this.precision)
      } else {
      }
    },
    ceilMoney(value) {
      let m = this.precision || 0
      return isNaN(Number(value)) ? 0 : Number(Number(value).toFixed(m))
    },
    priceFormat(num, n) {
      num = this.ceilMoney(num)
      n = n || 0
      if (num === null) return num
      if (typeof num !== 'number') throw new TypeError('num参数应该是一个number类型')
      if (n < 0) throw new Error('参数n不应该小于0')
      let hasDot = parseInt(num) != num//这里检测num是否为小数，true表示小数
      let m = (n != undefined && n != null) ? n : 1
      num = m == 0 ? num.toFixed(m) + '.' : hasDot ? (n ? num.toFixed(n) : num) : num.toFixed(m)
      num = Number(num).toLocaleString('en-us', { maximumFractionDigits: n })
      if (n == 0 || (!hasDot && !n)) {//如果n为0或者传入的num是整数并且没有指定整数的保留位数，则去掉前面操作中的小数位
        num = num.substring(0, num.indexOf('.'))
      }
      return num
    },
    checkValid(value) {
      const ret = this.digType_.test(value) && (this.max ? this.max >= Number(value) : true) && ((this.min || this.min == 0) ? this.min <= Number(value) : true)
      return ret
    },
    onfocus_() {
      this.value_ = this.rawvalue_
    },
    onblur_() {
      if (isVoid(this.rawvalue_)){
        this.rawvalue_ = this.min
      }
      if (isNotVoid(this.rawvalue_)) {
        this.value_ = this.formatMoney(this.rawvalue_)
        this.$emit('input', this.rawvalue_)
      }
    },
    oninput_(value) {
      if (value) {
        if (this.checkValid(value)) {
          this.rawvalue_ = Number(value)
        } else if (!isNaN(Number(value))) {
          this.value_ = this.ceilMoney(value)
          this.rawvalue_ = this.ceilMoney(value)
        } else {
          this.value_ = Number(this.min)
          this.rawvalue_ = Number(this.min)
        }
      } else {
        this.rawvalue_ = null
      }
      this.$emit('input', this.rawvalue_)
      this.$emit('update:value', this.rawvalue_)
    }
  }
}
</script>

<style scoped>
.left {
  text-align: left;
}

.right {
  text-align: right;
}
</style>
